package com.study.juc.lk;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: juc-study
 * @author: jzhou
 * @date: 2022-08-25 11:11
 * @version: 1.0
 * @description: 定制化唤醒
 **/
public class CustomizedSignalDemo {

	public static void main(String[] args) {
		Customized customized = new Customized();
		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				customized.printC1(i);
			}
		}, "AA").start();

		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				customized.printC2(i);
			}
		},"BB").start();

		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				customized.printC3(i);
			}
		},"CC").start();

	}
}

/**
 * 使用不同的标记来判断 中断和唤醒 指定线程
 * 让 c1 唤醒 c2 ，让 c2 唤醒 c3 ， 让 c3 唤醒 c1
 */
class Customized{

	private int flag = 1;
	private final Lock lock = new ReentrantLock();
	private final Condition c1  = lock.newCondition();
	private final Condition c2  = lock.newCondition();
	private final Condition c3  = lock.newCondition();

	public void printC1(int num){
		lock.lock();
		try {
			while (flag != 1){
				c1.await();
			}
			System.out.println(Thread.currentThread().getName() +"\t c1 " + num );
			flag = 2;
			c2.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printC2(int num){
		lock.lock();
		try {
			while (flag != 2){
				c2.await();
			}
			System.out.println(Thread.currentThread().getName() +"\t c2 " + num );
			flag = 3;
			c3.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printC3(int num){
		lock.lock();
		try {
			while (flag != 3){
				c3.await();
			}
			System.out.println(Thread.currentThread().getName() +"\t c3 " + num );
			flag = 1;
			c1.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}


}
